package org.kl.bf.sso;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.subject.WebSubject;
import org.apache.shiro.web.subject.WebSubject.Builder;
import org.kl.bf.entity.basic.CodeValues;
import org.kl.bf.entity.basic.DataDetail;
import org.kl.bf.entity.basic.DataRole;
import org.kl.bf.entity.basic.Role;
import org.kl.bf.entity.basic.User;
import org.kl.bf.service.basic.AccountService;
import org.kl.bf.service.basic.ShiroDbRealm.ShiroUser;
import org.kl.bf.utils.BasicConstants;
import org.kl.bf.web.base.BasicController;
import org.kl.auditsupervision.entity.fnd.Org;
import org.kl.auditsupervision.service.fnd.OrgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;

/**
 * 单点登录
 * 
 * @author QJ
 * @date 2015年1月20日
 */
@Controller
@RequestMapping(value = "/sso")
public class SSOController extends BasicController {
	@Autowired
	private AccountService accountService;
	@Autowired
	private OrgService orgService;
	@Autowired
	private SsoDao ssoDao;

	/**
	 * OA单点登录
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "oaLogin/{loginNo}/{sid}")
	public String oaLogin(@PathVariable(value = "loginNo") String loginNo, @PathVariable(value = "sid") String sid, HttpSession session,
			HttpServletRequest request, HttpServletResponse response) {
		// 检查sid合法性
		Integer cnt = ssoDao.checkOaSid(sid);
		if (cnt == 0) {
			throw new AuthenticationException("非法访问");
		}
		User user = accountService.findUserByLoginNo(loginNo);
		if (user != null && user.getEmployee() != null) {
			List<String> roleNoList = new ArrayList<String>();
			for (Role role : user.getRoleSet()) {
				roleNoList.add(role.getRoleNo());
			}
			Map<String, String> dataRoleMap = new HashMap<>();
			List<CodeValues> cvList = codeValuesService.findByTableCode(BasicConstants.TABLECODE_DATATYPE);
			if (cvList != null) {
				for (CodeValues cv : cvList) {// 防止没有给用户配置数据角色而导致IN搜索失效
					dataRoleMap.put(cv.getCodeName(), "null,");
				}
			}
			for (DataRole dataRole : user.getDataRoleSet()) {
				for (DataDetail dataDetail : dataRole.getDataDetailSet()) {
					if (dataRoleMap.containsKey(dataDetail.getDataType().getCodeName())) {
						if (!dataRoleMap.get(dataDetail.getDataType().getCodeName()).contains(dataDetail.getDataName())) {
							String str = dataRoleMap.get(dataDetail.getDataType().getCodeName()) + "," + dataDetail.getDataName();
							dataRoleMap.put(dataDetail.getDataType().getCodeName(), str);
						}
					} else {
						dataRoleMap.put(dataDetail.getDataType().getCodeName(), dataDetail.getDataName());
					}
				}
			}
			Org org = user.getEmployee().getOrg();
			String rootDeptCode = orgService.getOne(org.getRootOrgId()).getOrgNo();
			ShiroUser shiroUser = new ShiroUser(user.getId(), user.getLoginNo(), user.getTrueName(), org.getId(), org.getOrgNo(),
					rootDeptCode,org.getOrgName() , roleNoList, dataRoleMap, user.getSysManager());
			PrincipalCollection principals = new SimplePrincipalCollection(shiroUser, "SSORealm");
			Builder builder = new WebSubject.Builder(request, response);
			builder.principals(principals);
			builder.authenticated(true);
			WebSubject subject = builder.buildWebSubject();
			ThreadContext.bind(subject);
			//return "redirect:/bpm/confForm/form-viewHandleTaskPage?taskId=" + sid;
			return "redirect:/index";
		} else {
			throw new UnknownAccountException();// 没找到帐号
		}
	}
	
	
	/**
	 * 从其它系统单点登录过来
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "from/{loginNo}/{token}")
	public String from(@PathVariable(value = "loginNo") String loginNo, @PathVariable(value = "token") String token, HttpSession session,
			HttpServletRequest request, HttpServletResponse response) {
		// 检查token合法性
		Integer cnt = ssoDao.checkSsoToken(loginNo,token);
		if (cnt == 0) {
			throw new AuthenticationException("非法访问");
		}
		User user = accountService.findUserByLoginNo(loginNo);
		if (user != null && user.getEmployee() != null) {
			List<String> roleNoList = new ArrayList<String>();
			for (Role role : user.getRoleSet()) {
				roleNoList.add(role.getRoleNo());
			}
			Map<String, String> dataRoleMap = new HashMap<>();
			List<CodeValues> cvList = codeValuesService.findByTableCode(BasicConstants.TABLECODE_DATATYPE);
			if (cvList != null) {
				for (CodeValues cv : cvList) {// 防止没有给用户配置数据角色而导致IN搜索失效
					dataRoleMap.put(cv.getCodeName(), "null,");
				}
			}
			for (DataRole dataRole : user.getDataRoleSet()) {
				for (DataDetail dataDetail : dataRole.getDataDetailSet()) {
					if (dataRoleMap.containsKey(dataDetail.getDataType().getCodeName())) {
						if (!dataRoleMap.get(dataDetail.getDataType().getCodeName()).contains(dataDetail.getDataName())) {
							String str = dataRoleMap.get(dataDetail.getDataType().getCodeName()) + "," + dataDetail.getDataName();
							dataRoleMap.put(dataDetail.getDataType().getCodeName(), str);
						}
					} else {
						dataRoleMap.put(dataDetail.getDataType().getCodeName(), dataDetail.getDataName());
					}
				}
			}
			Org org = user.getEmployee().getOrg();
			String rootDeptCode = orgService.getOne(org.getRootOrgId()).getOrgNo();
			ShiroUser shiroUser = new ShiroUser(user.getId(), user.getLoginNo(), user.getTrueName(), org.getId(), org.getOrgNo(),
					org.getOrgName(), rootDeptCode, roleNoList, dataRoleMap, user.getSysManager());
			PrincipalCollection principals = new SimplePrincipalCollection(shiroUser, "SSORealm");
			Builder builder = new WebSubject.Builder(request, response);
			builder.principals(principals);
			builder.authenticated(true);
			WebSubject subject = builder.buildWebSubject();
			ThreadContext.bind(subject);
			ssoDao.finishSsoToken(loginNo, token);
			return "redirect:/";
		} else {
			throw new UnknownAccountException();// 没找到帐号
		}
	}
	
	/**
	 * 单点登录到其它系统
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "login/{targetSystem}")
	@ResponseBody
	public String login(@PathVariable(value = "targetSystem") String targetSystem, HttpSession session,
			HttpServletRequest request, HttpServletResponse response) {
		String token = UUID.randomUUID().toString().replace("-", "");
		ssoDao.insertSsoToken(token, getCurrentUserLoginName(), targetSystem);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("token", token);
		jsonObject.put("loginNo", getCurrentUserLoginName());
		jsonObject.put("targetSystem", targetSystem);
		return ajaxMsg("登录成功", true, jsonObject);
	}

}
